/*
 * CFJ-3000 - Phone system.
 *
 * (c) 2007 Cleiber Marques
 * (c) 2007 Filipe Medeiros
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 *
 */

#include "cfj.h"

/* The names of functions that actually do the manipulation. */
int cmd_connect (char *arg);
int cmd_hangup (char *arg);
int cmd_accept (char *arg);
int cmd_deny (char *arg);
int cmd_quit (char *arg);
int cmd_help (char *arg);

/* A structure which contains information on the commands this program
   can understand. */

typedef struct {
  char *name;			/* User printable name of the function. */
  int (*func) (char *str);	/* Function to call to do the job. */
  char *doc;			/* Documentation for this function.  */
} COMMAND;

COMMAND commands[] = {
  { "connect", cmd_connect, "Connects to the remote host" },
  { "hangup", cmd_hangup, "Breaks current connection" },
  { "accept", cmd_accept, "Accept connections"},
  { "deny", cmd_deny, "Deny connections"},
  { "help", cmd_help, "Prints this help screen" },
  { "quit", cmd_quit, "Quit using CFJ-3000" },
  { (char *)NULL, NULL, (char *)NULL }
};

/* Forward declarations. */
char *stripwhite (char *string);
COMMAND *find_command (char *name);
int execute_line (char *line);
int valid_argument (char *caller, char *arg);
int done = TRUE;

int terminal ()
{
  char *line, *s;
   printf(" _____\n"
"(.---.)-._.-.\n"
" /:::\\ _.---'\tWelcome to CFJ-3000 version %s\n"
"'-----'\n",CFJ_VERSION);

   //printf("Welcome to CFJ-3000 version %s\n",CFJ_VERSION);

  /* Loop reading and executing lines until the user quits. */
  while (done)
    {
      line = readline ("CFJ-3000> " );

      if (!line)
        break;

      /* Remove leading and trailing whitespace from the line.
         Then, if there is anything left, add it to the history list
         and execute it. */
      s = stripwhite (line);

      if (*s)
        {
          add_history (s);
          execute_line (s);
        }

      free (line);
    }
  exit (0);
}

/* Execute a command line. */
int execute_line (char *line)
{
  int i;
  COMMAND *command;
  char *word;

  /* Isolate the command word. */
  i = 0;
  while (line[i] && whitespace (line[i]))
    i++;
  word = line + i;

  while (line[i] && !whitespace (line[i]))
    i++;

  if (line[i])
    line[i++] = '\0';

  command = find_command (word);

  if (!command)
    {
      printf ("%s: No such command for CFJ-3000.\n", word);
      return (-1);
    }

  /* Get argument to command, if any. */
  while (whitespace (line[i]))
    i++;

  word = line + i;

  /* Call the function. */
  return ((*(command->func)) (word));
}

/* Look up NAME as the name of a command, and return a pointer to that
   command.  Return a NULL pointer if NAME isn't a command name. */
COMMAND *find_command (char *name)
{
  int i;

  for (i = 0; commands[i].name; i++)
    if (strcmp (name, commands[i].name) == 0)
      return (&commands[i]);

  return ((COMMAND *)NULL);
}

/* Strip whitespace from the start and end of STRING.  Return a pointer
   into STRING. */
char *stripwhite (char *string)
{
  register char *s, *t;

  for (s = string; whitespace (*s); s++)
    ;
  if (*s == 0)
    return (s);

  t = s + strlen (s) - 1;
  while (t > s && whitespace (*t))
    t--;
  *++t = '\0';

  return s;
}

/* Cfj Commands */
int cmd_connect (char *arg)
{
  pthread_t socktcp;
  int res;
  if (!valid_argument ("connect", arg))
    return (1);
  if(server_status == BUSY || client_status == BUSY){
    printf("First hangup\n");
    return (1);
  }
  strcpy(their_ip, arg);
  if((res = pthread_create(&socktcp, NULL, tcp_client, NULL)) != 0){
      perror("Thread creation failed\n");
      exit(1);
   }
  return(0);
}

int cmd_hangup(char *arg)
{
  if(server_status == BUSY){
    send(sockfd_server,"EOT", 4, 0);
    return (0);
  }
  if(client_status == BUSY){
    send(sockfd_client,"EOT", 4, 0);
    return (0);
  }
  printf("None connection.\n");
  return (1);
}

int cmd_accept(char *arg)
{
  if(server_status == !BUSY) {
    printf("Not request connection.\n");
    return (1);
  }
  if(server_status == ENQ_ACK){
    printf("You have one connection.\n");
    return (1);
  }
  enq_status = ENQ_ACK;
  return (0);
}

int cmd_deny(char *arg)
{
  if(server_status == !BUSY) {
    printf("Not request connection.\n");
    return (1);
  }
  if(server_status == ENQ_ACK){
    printf("You have one connection.\n");
    return (1);
  }
  enq_status = ENQ_NACK;
  return (0);
}

/* Print out help for ARG, or for all of the commands if ARG is
   not present. */
int cmd_help (char *arg)
{
  int i;
  int printed = 0;

  for (i = 0; commands[i].name; i++)
    {
      if (!*arg || (strcmp (arg, commands[i].name) == 0))
        {
          printf ("%s\t\t%s.\n", commands[i].name, commands[i].doc);
          printed++;
        }
    }

  if (!printed)
    {
      printf ("No commands match `%s'.  Possibilties are:\n", arg);

      for (i = 0; commands[i].name; i++)
        {
          /* Print in four columns. */
          if (printed == 4)
            {
              printed = 0;
              printf ("\n");
            }

          printf ("%s\t", commands[i].name);
          printed++;
        }

      if (printed)
        printf ("\n");
    }
  return (0);
}

/* The user wishes to quit using this program.  Just set DONE
   zero. */
int cmd_quit (char *arg)
{
  done = FALSE;
  return (0);
}

/* Return non-zero if ARG is a valid argument for CALLER,
   else print an error message and return zero. */
int valid_argument (char *caller, char *arg)
{
  if (!arg || !*arg)
    {
      printf ("%s: Argument required.\n", caller);
      return (0);
    }

  return (1);
}
